package pl.wroc.uni.ii.evolution.engine.prototype;

import java.io.Serializable;

/**
 * Basic abstract class for creation of individuals. Should
 * provide custom methods for accessing it's contents.
 * 
 * @author Marcin Brodziak, Tomasz Kozakiewicz
 */
public abstract class EvIndividual implements Serializable, Comparable, Cloneable {
  private double objective;

  private boolean objective_calculated = false;

  private EvObjectiveFunction objective_function = null;

  public void setObjectiveFunction(EvObjectiveFunction function) {
	  this.invalidate();
    objective_function = function;
  }
  
  public EvObjectiveFunction getObjectiveFunction() {
    return objective_function;
  }

  /**
   * Lazy evaluation of objective function.
   * 
   * @return value of objective function.
   */
  @SuppressWarnings("unchecked")
  public double getObjectiveFunctionValue() {
    if (objective_function == null) {
      throw new IllegalStateException("Objective function is not set.");
    }

    if (!objective_calculated) {
      objective = objective_function.evaluate(this);
    }
    objective_calculated = true;
    return objective;
  }

  /**
   * Must be marked when any kind of modification of 
   * internal state that changes value of objective function
   * is calculated.
   */
  protected void invalidate() {
    objective_calculated = false;
  }
  
  protected void uninvalidate(double objective_function_value) {
    this.objective = objective_function_value;
    objective_calculated = true;
  }
  
  protected boolean isValidate() {
    return objective_calculated;
  }
  
  public int compareTo(Object o) {
    EvIndividual individual = (EvIndividual)o;
    if (individual.getObjectiveFunctionValue() > getObjectiveFunctionValue())
      return -1;
    else if (individual.getObjectiveFunctionValue() < getObjectiveFunctionValue())
      return 1;
    return 0;
  }
  
  public abstract Object clone();
}
 